package org.maylove.wuziqi.service;

import jakarta.websocket.server.ServerEndpoint;
import org.maylove.wuziqi.common.PasswordProcess;
import org.maylove.wuziqi.common.RedisUtil;
import org.maylove.wuziqi.dao.UserDao;
import org.maylove.wuziqi.game.GameManager;
import org.maylove.wuziqi.pojo.user.User;
import org.maylove.wuziqi.pojo.user.dto.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    UserDao userDao;


    @Autowired
    ApplicationEventPublisher eventPublisher;

    @Override
    public String register(UserRegisterDto userRegisterDto) {
        //  检查用户名长度，要求6-16位非空
        if(userRegisterDto.getUsername().length() < 6 || userRegisterDto.getUsername().length() > 16) {
            return "The username format does not meet the requirements!";
        }

        //  检查密码长度，要求8-16位非空
        if(userRegisterDto.getPassword().length() < 8 || userRegisterDto.getPassword().length() > 16) {
            return "The password format does not meet the requirements!";
        }

        //  检查昵称，要求16位以内非空
        if(userRegisterDto.getNickname().isEmpty() || userRegisterDto.getNickname().length() > 16) {
            return "The nickname format does not meet the requirements!";
        }

        //  检查数据库里面是否存在该用户名
        User user = userDao.findByUsername(userRegisterDto.getUsername());
        if (user != null) {
            return "The username already exists!";
        }

        user = new User();
        BeanUtils.copyProperties(userRegisterDto, user);
        Long timestamp = java.time.Instant.now().toEpochMilli();
        user.setUserId(timestamp);
        user.setPassword(PasswordProcess.encrypt(userRegisterDto.getPassword()));
        user.setTotGameNum(0);
        user.setWinGameNum(0);
        user.setIdentity(0);
        userDao.save(user);
        return "User has saved!";
    }

    @Override
    public Object login(UserLoginDto userLoginDto) {
        User user =userDao.findByUsername(userLoginDto.getUsername());
        if(user == null) {
            return "Username does not exist!";
        }
        if(!PasswordProcess.matches(userLoginDto.getPassword(), user.getPassword())) {
            return "Wrong password!";
        }
        UserDto userDto = new UserDto();
        BeanUtils.copyProperties(user, userDto);
        return userDto;
    }

    @Override
    public String changeNicknam(Long userId, UserChangeNickNameDto userChangeNickNameDto) {
        //  检查昵称，要求16位以内非空
        if(userChangeNickNameDto.getNickname().isEmpty() || userChangeNickNameDto.getNickname().length() > 16) {
            return "The nickname format does not meet the requirements!";
        }

        User user = userDao.findByUserId(userId);
        if(user == null) {
            return "UserId does not exist!";
        }
        //  检查密码是否出错
        if(!PasswordProcess.matches(userChangeNickNameDto.getPassword(), user.getPassword())) {
            return "Wrong password!";
        }
        user.setNickname(userChangeNickNameDto.getNickname());
        userDao.save(user);
        return "User has changed!";
    }

    @Override
    public String changePassword(Long userId, UserChangePasswordDto userChangePasswordDto) {
        //  检查密码长度，要求8-16位非空
        if(userChangePasswordDto.getNewPassword().length() < 8 || userChangePasswordDto.getNewPassword().length() > 16) {
            return "The new password format does not meet the requirements!";
        }

        User user = userDao.findByUserId(userId);
        if(user == null) {
            return "UserId does not exist!";
        }
        //  检查密码是否出错
        if(!PasswordProcess.matches(userChangePasswordDto.getOldPassword(), user.getPassword())) {
            return "Wrong old password!";
        }
        user.setPassword(PasswordProcess.encrypt(userChangePasswordDto.getNewPassword()));
        userDao.save(user);
        return "User has changed!";
    }

    @Override
    public UserDto getUserInfo(Long userId) {
        User user = userDao.findByUserId(userId);
        if(user == null) {
            return null;
        }
        UserDto userDto = new UserDto();
        BeanUtils.copyProperties(user, userDto);
        return userDto;
    }

    @Override
    public Integer createRoom(Long userId) {
        GameManager gameManager = GameManager.getInstance(eventPublisher);
        return gameManager.getRoom(userId);
    }

    @Override
    public Integer joinRoom(Long userId, int roomId) {
        GameManager gameManager = GameManager.getInstance(eventPublisher);
        return gameManager.joinRoom(userId, roomId);
    }

    @Override
    public void win(Long userId) {
        User user = userDao.findByUserId(userId);
        user.setWinGameNum(user.getWinGameNum() + 1);
        user.setTotGameNum(user.getTotGameNum() + 1);
        userDao.save(user);
    }

    @Override
    public void fail(Long userId) {
        User user = userDao.findByUserId(userId);
        user.setTotGameNum(user.getTotGameNum() + 1);
        userDao.save(user);
    }

    @Override
    public UserSimpleDto getSimpleUser(Long userId) {
        User user = userDao.findByUserId(userId);
        UserSimpleDto dto = new UserSimpleDto();
        BeanUtils.copyProperties(user, dto);
        return dto;
    }

    @Override
    public Integer getIdentity(Long userId) {
        User user = userDao.findByUserId(userId);
        if(user == null) {
            return 0;
        }
        return user.getIdentity();
    }

    @Override
    public String getNickname(Long userId) {
        User user = userDao.findByUserId(userId);
        if(user == null) {
            return "";
        }
        return user.getNickname();
    }

    @Override
    public void changeIdentity(UserChangeIdentityDto userChangeIdentityDto) {
        User user = userDao.findByUserId(userChangeIdentityDto.getUserId());
        if(user != null) {
            user.setIdentity(userChangeIdentityDto.getIdentity());
            userDao.save(user);
        }
    }

    @Override
    public List<UserGetDto> getUser(UserPageDto userPageDto) {
        List<User> users=userDao.getUser((userPageDto.getPageNum()-1)* userPageDto.getPageSize(), userPageDto.getPageSize());
        int size=users.size();
        List<UserGetDto> userGetDtos=new ArrayList<UserGetDto>();
        for(int i=0;i<size;i++) {
            UserGetDto userGetDto=new UserGetDto();
            BeanUtils.copyProperties(users.get(i),userGetDto);
            userGetDtos.add(userGetDto);
        }
        return userGetDtos;
    }
}
